#pragma once
#include "Global.h"

class RedisConPool {
 public:
  RedisConPool(std::size_t poolSize, std::string host, short port,
               std::string password);
  ~RedisConPool();
  redisContext *GetConnect();
  void ReleaseConnect(redisContext *con);
  void Close();

 private:
  short _port;
  std::string _host;
  std::string _password;
  std::size_t _poolSize;
  std::queue<redisContext *> _pool;
  atomic<bool> _stop;
  std::mutex _mutex;
  std::condition_variable _cond;
};

class RedisMgr : public Singleton<RedisMgr> {
  friend class Singleton<RedisMgr>;

 public:
  ~RedisMgr();
  bool Set(const std::string &key, const std::string &value);
  bool Get(const std::string &key, std::string &value);
  bool LPush(const std::string &key, const std::string &value);
  bool LPop(const std::string &key, std::string &value);
  bool RPush(const std::string &key, const std::string &value);
  bool RPop(const std::string &key, std::string &value);
  bool HSet(const std::string &key, const std::string &field,
            const std::string &value);
  bool HSet(const char *key, const char *hkey, const char *field,
            size_t hvaluelen);
  std::string HGet(const std::string &key, const std::string &hkey);
  bool Del(const std::string &key);
  bool Exists(const std::string &key);
  void Close();

 private:
  RedisMgr();

  std::unique_ptr<RedisConPool> _connPool;
};
